package org.jeecg.modules.vue;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.vue.drawpool.entity.DrawPool;
import org.jeecg.modules.vue.drawpool.mapper.DrawPoolMapper;
import org.jeecg.modules.vue.drawpool.service.IDrawPoolService;
import org.jeecg.modules.vue.knapsack.entity.Knapsack;
import org.jeecg.modules.vue.knapsack.mapper.KnapsackMapper;
import org.jeecg.modules.vue.prop.entity.Prop;
import org.jeecg.modules.vue.prop.mapper.PropMapper;
import org.jeecg.modules.vue.starlightsetmeal.entity.StarlightSetMeal;
import org.jeecg.modules.vue.starlightsetmeal.mapper.StarlightSetMealMapper;
import org.jeecg.modules.vue.wallet.entity.Wallet;
import org.jeecg.modules.vue.wallet.mapper.WalletMapper;
import org.jeecg.modules.vue.wallet.service.IWalletService;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DrawPoolService {

    @Resource
    private DrawPoolMapper drawPoolMapper;

    @Resource
    private PropMapper propMapper;

    @Resource
    private WalletMapper walletMapper;
    @Resource
    private IWalletService walletService;

    @Resource
    private KnapsackMapper knapsackMapper;

    @Resource
    private StarlightSetMealMapper starlightSetMealMapper;

    @Autowired
    private IDrawPoolService drawPoolService;

    /***奖池列表*@return*/
    public Map list(Integer currentUserId) {

        Map result = new HashMap<>();
        QueryWrapper<DrawPool> drawPoolQueryWrapper = new QueryWrapper<>();
        List<DrawPool> drawPoolList = drawPoolMapper.selectList(drawPoolQueryWrapper);
//        drawPoolService.list();


        for (DrawPool drawPool : drawPoolList) {

            drawPool.setPropInfo(propMapper.selectById(drawPool.getPropId()));

        }

        //封装奖品信息
        result.put("prop", drawPoolList);

        //封装幸运值上限，暂定500
        result.put("upperLucky", 500);

        //封装用户星云币、积分、幸运值信息
        if (currentUserId != null) {

            result.put("walletInfo", walletMapper.selectByUserId(currentUserId));

        } else {

            result.put("walletInfo", null);

        }

        List starlightSetMeals = starlightSetMealMapper.selectByType(2);

        result.put("starlightSetMeals", starlightSetMeals);

        return result;

    }

    /***
     * 抽奖
     * @param currentUserId 抽奖用户
     * @param starlightSetMealId  抽奖套餐ID
     * @return*/
    public Result<?> luckDraw(int currentUserId, int starlightSetMealId) {

        Map result = new HashMap<>();

        List propList = new ArrayList<>();

        Wallet wallet = walletMapper.selectByUserId(currentUserId);

        StarlightSetMeal starlightSetMeal = starlightSetMealMapper.selectById(starlightSetMealId);

        if (wallet == null || starlightSetMeal == null) {

            return Result.error("不满足抽奖条件");

        }

        //此次抽奖应该消耗的积分
        int usrStarlight = starlightSetMeal.getPrice().intValue();

        int num = starlightSetMeal.getAmount();

        if (wallet.getStarlight() < usrStarlight) {

            return Result.error("积分不足");

        }

        //更新积分数量， 积分不用记录账单
        wallet.setStarlight(wallet.getStarlight() - usrStarlight);

        walletService.updateById(wallet);
//    walletMapper.updateByPrimaryKeySelective(wallet);

//一号奖池上限
        int oneUpperLucky = 200;

//二号奖池上限
        int towUpperLucky = 300;

        boolean isResetLucky = false;

        for (int i = 0; i < num; i++) {

//更新幸运值
            wallet = walletMapper.selectByUserId(currentUserId);

//返回抽奖池列表结果
            List drawPoolList = new ArrayList<>();

//根据幸运值获取不同的抽奖池
            if (wallet.getLucky() >= 0 && wallet.getLucky() < towUpperLucky) {

                drawPoolList.addAll(drawPoolMapper.selectByType(1));

            }

            if (wallet.getLucky() >= towUpperLucky && wallet.getLucky() < oneUpperLucky) {

                drawPoolList.addAll(drawPoolMapper.selectByType(2));

            }

            if (wallet.getLucky() >= oneUpperLucky) {

                //如果当前用户的幸运值大于550，必得特殊道具
                drawPoolList.addAll(drawPoolMapper.selectByType(3));

                isResetLucky = true;

            }

            int prizeId = getPrizeIndex(drawPoolList);

            //如果奖品是价值点之类的，直接增加
            Prop prop = propMapper.selectById(prizeId);

            if (prop.getType() == 2) {

                wallet.setStarlight(wallet.getStarlight() + prop.getNum());
                walletService.updateById(wallet);
//                walletMapper.updateByPrimaryKeySelective(wallet);

            } else {

                //如果是道具，就存放到用户背包
                Knapsack knapsack = knapsackMapper.getKnapsack(currentUserId, Knapsack.Type.PROP, prizeId);

                if (oConvertUtils.isEmpty(knapsack)) {

                    knapsack = new Knapsack();

                    knapsack.setUserId(currentUserId);

                    knapsack.setGiftId(prizeId);

                    knapsack.setType(Knapsack.Type.PROP);

                    knapsack.setNumble(prop.getNum());

                    knapsackMapper.insert(knapsack);

                } else {

                    knapsack.setNumble(knapsack.getNumble() + prop.getNum());

//                    knapsackMapper.updateByPrimaryKeySelective(knapsack);
                    walletService.updateById(wallet);
                }

            }

            //没进行一轮如果抽到了特殊奖池，那么都要清空幸运值，不然如果是多次抽奖，那么后面的每次都会是特殊道具
            if (isResetLucky) {
                //清空幸运值
                wallet.setLucky(0);
//                walletMapper.updateByPrimaryKeySelective(wallet);
                walletService.updateById(wallet);
            } else {
                //增加 幸运值,每抽奖一次， 幸运值+1
                wallet.setLucky(wallet.getLucky() + 1);
//                walletMapper.updateByPrimaryKeySelective(wallet);
                walletService.updateById(wallet);
            }
            propList.add(prop);
        }
        //清空幸运值
        if (isResetLucky) {
            wallet.setLucky(0);
//            walletMapper.updateByPrimaryKeySelective(wallet);
            walletService.updateById(wallet);
        }
        result.put("propList", propList);
        //封装用户积分、幸运值信息
        result.put("walletInfo", walletMapper.selectByUserId(currentUserId));
        return Result.OK(result);

    }

    /***中奖概率，总概率的多少分之一，如果所有道具的概率总和为100当前奖品的概率是1，那么中奖概率就是百分之一
     *根据Math.random()产生一个double型的随机数，判断每个奖品出现的概率
     *@param drawPools
     *@return random：奖品列表drawPools中的序列(drawPools中的第random个就是抽中的奖品),返回中奖的道具ID
     * */
    public static int getPrizeIndex(List<DrawPool> drawPools) {
        // DecimalFormat df = new DecimalFormat("######0.00");
        int prizeId = 0;
        try {
            //计算总权重
            double sumWeight = 0;
            for (DrawPool drawPool : drawPools) {
                sumWeight += drawPool.getProbability();
            }
            //产生随机数
            double randomNumber;
            randomNumber = Math.random();
            //根据随机数在所有奖品分布的区域并确定所抽奖品
            double d1 = 0;
            double d2 = 0;
            for (int i = 0; i < sumWeight; i++) {
                //依次获取奖品所在的范围//获取当前奖品所在的中奖概率范围 最大值
                d2 += Double.parseDouble(String.valueOf(drawPools.get(i).getProbability())) / sumWeight;
                if (i == 0) {
                    d1 = 0;
                } else {
                    //获取上一个奖品所在的中奖概率范围 最大值
                    d1 += Double.parseDouble(String.valueOf(drawPools.get(i - 1).getProbability())) / sumWeight;
                }
                //如果中奖随机数 大于上一个奖品的最大值 并且小于当前奖品的最大值，那么表示中奖随机数在当前奖品的中奖范围内，当前奖品中奖
                if (randomNumber >= d1 && randomNumber <= d2) {
                    prizeId = drawPools.get(i).getPropId();
                    break;
                }
            }
        } catch (Exception e) {
            System.out.println("生成抽奖随机数出错，出错原因：" + e.getMessage());
        }
        return prizeId;
    }
}